/*
 * @Author: your name
 * @Date: 2020-05-06 11:07:13
 * @LastEditTime: 2020-08-04 12:56:36
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \truck\platform\main.c
 */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <execinfo.h> 

#include "xeLOG_internal.h"

#include "global_common.h"

#include "xeSqlite.h"
#include "file_space.h"

#include "my_timer.h"

int _log_level = 7; // for internal

// {
// 	STD_print("%d %d %d",sizeof(time_t),sizeof(long int),sizeof(long long));
//	for 64 bit 8 8 8
// 	exit(0);
// }
static int __sig_handle_calling=0;
#define BACKTRACE_NUM 30
void __my_sig_handle(int signum){
	
	xeLOG_ERR("get signal %d.",signum);
	STD_print("get signal %d.",signum);
	if(signum == 54)
		return;

	if(signum == SIGHUP)
		return;

	if(signum == SIGPIPE)
		return;

	if(signum == SIGTSTP)
		return;

	if(signum == SIGWINCH)
		return;

	if ( signum == SIGSEGV ) {
		char tracefile[128] = {0};
		void *trace[BACKTRACE_NUM];
		snprintf( tracefile, sizeof(tracefile)-1, "%s/alarm_strace", "./" );
		int n = backtrace(trace, BACKTRACE_NUM);
		int fd = open( tracefile, O_CREAT | O_WRONLY | O_APPEND, 0777 );
		if ( fd == -1 ) {
			backtrace_symbols_fd(trace, n, STDERR_FILENO);
		} else {
			char *cutoff = "---------------------\r\n";
			backtrace_symbols_fd(trace, n, fd);
			if ( write( fd, cutoff, strlen( cutoff )) > 0 )
				fdatasync( fd );
			close( fd );
		}
	}

	if ( __sig_handle_calling ) {
		return;
	}
	__sig_handle_calling = 1;
	

	if(signum!=499)
		sync();
	
	usleep(10000);

	exit(-1);
}

int signal_handle()
{
	int tuy;
	for( tuy = 1; tuy <=64; tuy++)
	{
		if ( tuy == SIGCHLD ) { continue; }
		if ( tuy == SIGCONT ) { continue; }
		if ( tuy == SIGALRM ) { continue; }
		if ( tuy == SIGTTIN ) { continue; }

		signal(tuy, __my_sig_handle);
	}
	return 0;
}

static int init_core_log(int tmp_log_level)
{
	int ret = 0;

#define logPath "/root/log"
#ifdef CONFIG_USE_EXTERNAL_XELOG
	init_xelog_local_t init = {0};
	if(access(logPath, F_OK) != 0){
		printf("%s is not exit, shoud be build \n", logPath);
		if(mkdir(logPath, 0755) == -1){   
		printf("mkdir %s error \n", logPath);   
		return -1;   
		}  
	}else{
		printf("%s is exit \n ", logPath);
	}
	init.local_port = 0;
	init.be_syslog  = 0;
	init.be_klog    = 0;
	init.log_level  = tmp_log_level;

	strcpy(init.path, logPath);

	init.num  = 20;
	init.size = 1*1024*1024;
	init.msg2stdout  = 0;
	if(tmp_log_level > 10)
		init.msg2stderr = 1;

	ret=init_xelog_local(&init);
	if(ret != 0) {
		xeLOG_ERR("init_xelog local fail.");
	}

	dprintf("init_xelog local success.\n");
#else
	_log_level = tmp_log_level;
#endif
	return ret;
}
int create_dw_free_cache_thread(void *arg);
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  main
 *  Description:  2020-3-25 15:51:18
 * =====================================================================================
 */
int main(int argc, char **argv)
{
	int retval;
	int log_para = 5;
	if (2 == argc){
		log_para = atoi(argv[1]);
		STD_print("input log level %d",log_para);
	}
	init_core_log(log_para);

	xeLOG_NOTICE("stroage server start...\n");
	signal_handle();
	
	timer_sched_init();

	tiny_rec_sqlite_main();

	tiny_space_init();

	create_dw_free_cache_thread(NULL);

	tiny_http_main();
	while(1)
		pause();

	return 0;
}

 int get_free_memory ( )
 {
	 static FILE* fd = NULL;
	 static int memfree = 0;
	 static char buff[128] = {0};
	 static char memstr[64] = {0};
	 static char unit[32] = {0};
 
	 fd = fopen("/proc/meminfo", "r" );
	 if ( fd == NULL ) {
		 return -1;
	 }
 
	 do{
		 if (fgets (buff, sizeof(buff), fd) == NULL )
			 break;
		 if (sscanf (buff, "%s %d %s", memstr, &memfree, unit) != 3 )
			 continue;
		 if (strcmp( memstr, "MemFree:" ) == 0 ) {
			 fclose(fd); 
			 return memfree;
		 }
	 } while(20200727);
 
	 fclose(fd); 
	 return -1;
 }
 void free_pagecache ( )
 {
     
     int ret = -1;
	 static int fd;//, fd1;
	 static char *data = "3";
	 fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
	 write(fd, data, sizeof(char));
	 close(fd);
 }
int dw_free_cache()
{
	int memfree = 0;
	while(20200726){
		memfree = get_free_memory();
		xeLOG_WARNING("dw get memory %d",memfree>>10);
		if (memfree > 0 && (memfree>>10) < 5000) {
			free_pagecache();
		}
		sleep(3600);
	}
}
int create_dw_free_cache_thread(void *arg)
{
	pthread_t	detected_tid;
    if (0 != pthread_create(&detected_tid, NULL, dw_free_cache, (void*)(arg)))
    {
        STD_print("create dw_free_cache failed.\n");
		xeLOG_ERR("create dw_free_cache failed.\n");
        return -1;
    }
    STD_print("create dw_free_cache success\n");
    xeLOG_NOTICE("create dw_free_cache success\n");
	return 0;
}